/**
 * A revolute joint constrains two bodies to share a common point while they
 * are free to rotate about the point. The relative rotation about the shared
 * point is the joint angle. You can limit the relative rotation with
 * a joint limit that specifies a lower and upper angle. You can use a motor
 * to drive the relative rotation about the shared point. A maximum motor torque
 * is provided so that infinite forces are not generated.
**/
public class b2RevoluteJoint extends b2Joint {
	public b2RevoluteJoint(int addr) {
		super(addr);
	}

	@Override
	public void release() {
		if ( address != 0 ) {
			super.release();
		}
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetAnchorA() {
		return new b2Vec2(jniGetAnchorA(address));
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetAnchorB() {
		return new b2Vec2(jniGetAnchorB(address));
	}

	/// The local anchor point relative to bodyA's origin.
	public b2Vec2 GetLocalAnchorA() {
		return new b2Vec2(jniGetLocalAnchorA(address));
	}

	/// The local anchor point relative to bodyB's origin.
	public b2Vec2 GetLocalAnchorB() {
		return new b2Vec2(jniGetLocalAnchorB(address));
	}

	/// Get the reference angle.
	public float GetReferenceAngle() {
		return jniGetReferenceAngle(address);
	}

	/// Get the current joint angle in radians.
	public float GetJointAngle() {
		return jniGetJointAngle(address);
	}

	/// Get the current joint angle speed in radians per second.
	public float GetJointSpeed() {
		return jniGetJointSpeed(address);
	}

	/// Is the joint limit enabled?
	public boolean IsLimitEnabled() {
		return jniIsLimitEnabled(address);
	}

	/// Enable/disable the joint limit.
	public void EnableLimit(boolean flag) {
		jniEnableLimit(address, flag);
	}

	/// Get the lower joint limit, usually in meters.
	public float GetLowerLimit() {
		return jniGetLowerLimit(address);
	}

	/// Get the upper joint limit, usually in meters.
	public float GetUpperLimit() {
		return jniGetUpperLimit(address);
	}

	/// Set the joint limits, usually in meters.
	public void SetLimits(float lower, float upper) {
		jniSetLimits(address, lower, upper);
	}

	/// Is the joint motor enabled?
	public boolean IsMotorEnabled() {
		return jniIsMotorEnabled(address);
	}

	/// Enable/disable the joint motor.
	public void EnableMotor(boolean flag) {
		jniEnableMotor(address, flag);
	}

	/// Set the motor speed in radians per second.
	public void SetMotorSpeed(float speed) {
		jniSetMotorSpeed(address, speed);
	}

	/// Get the motor speed in radians per second.
	public float GetMotorSpeed() {
		return jniGetMotorSpeed(address);
	}

	/// Set the maximum motor torque, usually in N-m.
	public void SetMaxMotorTorque(float torque) {
		jniSetMaxMotorTorque(address, torque);
	}

	public float GetMaxMotorTorque() {
		return jniGetMaxMotorTorque(address);
	}

	/// Get the reaction force given the inverse time step.
	/// Unit is N.
	public b2Vec2 GetReactionForce(float inv_dt) {
		return new b2Vec2(jniGetReactionForce(address));
	}

	/// Get the reaction torque due to the joint limit given the inverse time step.
	/// Unit is N*m.
	public float GetReactionTorque(float inv_dt) {
		return jniGetReactionTorque(address, inv_dt);
	}

	/// Get the current motor torque given the inverse time step.
	/// Unit is N*m.
	public float GetMotorTorque(float inv_dt) {
		return jniGetMotorTorque(address, inv_dt);
	}

	/// Dump to b2Log.
	public void Dump() {
		throw new UnsupportedOperationException();
	}

	private static native int jniGetAnchorA(int me);
	private static native int jniGetAnchorB(int me);
	private static native int jniGetLocalAnchorA(int me);
	private static native int jniGetLocalAnchorB(int me);
	private static native float jniGetReferenceAngle(int me);
	private static native float jniGetJointAngle(int me);
	private static native float jniGetJointSpeed(int me);
	private static native boolean jniIsLimitEnabled(int me);
	private static native void jniEnableLimit(int me, boolean flag);
	private static native float jniGetLowerLimit(int me);
	private static native float jniGetUpperLimit(int me);
	private static native void jniSetLimits(int me, float lower, float upper);
	private static native void jniEnableMotor(int me, boolean flag);
	private static native boolean jniIsMotorEnabled(int me);
	private static native float jniGetMotorSpeed(int me);
	private static native void jniSetMotorSpeed(int me, float speed);
	private static native float jniGetMaxMotorTorque(int me);
	private static native void jniSetMaxMotorTorque(int me, float torque);
	private static native int jniGetReactionForce(int me);
	private static native float jniGetReactionTorque(int me, float inv_dt);
	private static native float jniGetMotorTorque(int me, float inv_dt);
}
